home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / ddjgrep.zip / QUEUE.C < prev    next >
Text File  |  1987-11-04  |  5KB  |  207 lines

  1. #ifdef DEBUG
  2. #include <stdio.h>
  3. #endif
  4.  
  5. /*-------------------------------------------------------------------
  6.  *    QUEUE.C:    General purpose queue management routines:
  7.  *
  8.  *     Copyright (c) 1985, Allen I. Holub.  All rights reserved
  9.  *  This program may be copied for personal, non-profit, use only.
  10.  *-------------------------------------------------------------------
  11.  *
  12.  *  The QUEUE data structure. No external routine needs to know anything
  13.  *  about how this structure is put together. These routines need only
  14.  *  remember a pointer to the queue (in a manner similar to the FILE
  15.  *  pointer used by the i/o routines).
  16.  */
  17.  
  18. typedef struct
  19. {
  20.     char    *start;        /* Pointer to beginning of queue    */
  21.     int    head;        /* Index of current head         */
  22.     int    tail;        /* Index of current tail         */
  23.     int    size;        /* Max num of objects queue can hold    */
  24.     int    nobj;        /* Number of objects now in the queue    */
  25.     int    objsize;    /* Size of one element             */
  26. } QUEUE;
  27.  
  28. /*----------------------------------------------------------------------*/
  29.  
  30. QUEUE    *makequeue( qsize, objsize )
  31. {
  32.     /* Make a queue of the specified size containing objects of the
  33.      * specified size. Return a pointer to the queue or 0 if there is
  34.      * not enough memory to make the queue. Queues are created using
  35.      * calloc(). They require sizeof(QUEUE) + (qsize * objsize) bytes.
  36.      */
  37.  
  38.     register QUEUE    *qp;
  39.  
  40.     if( !(qp = (QUEUE *) malloc(sizeof(QUEUE) + (qsize * objsize)) ))
  41.         return 0;
  42.  
  43.     qp->start     = (char *)(qp + 1); 
  44.     qp->size     = qsize   ;
  45.     qp->objsize    = objsize ;
  46.  
  47.     qp->head = qp->tail = qp->nobj = 0;
  48.  
  49.     return( qp );
  50. }
  51.  
  52. del_queue( qp )
  53. QUEUE    *qp;
  54. {
  55.     /*   Delete a queue and free the memory. The queue will NOT
  56.      *   be deleted unless it is empty. Return 1 if the queue
  57.      *   was deleted, 0 otherwise. If you don't care if the queue
  58.      *   is actually empty, use free(qp).
  59.      */
  60.  
  61.     if( qp->nobj )
  62.         return 0;
  63.  
  64.     free( qp );
  65.     return 1;
  66. }
  67.  
  68. /*----------------------------------------------------------------------*/
  69.  
  70. enqueue( obj, qp )
  71. char    *obj ;
  72. QUEUE    *qp  ;
  73. {
  74.     /*    Put an object into the queue. Obj is a pointer to the
  75.      *    object qp is a pointer to a QUEUE. Return 1 on success,
  76.      *    0 if there's no more room in the queue.
  77.      */
  78.  
  79.     int    i;                /* Counter        */
  80.     char    *bp;                /* points into queue    */
  81.  
  82.     if( qp->nobj  >=  qp->size )        /* If the queue is full */
  83.         return 0;            /* return failure.    */
  84.  
  85.     qp->nobj++;                /* One more object in    */
  86.                         /* the queue        */
  87.  
  88.     bp= qp->start + (qp->objsize * qp->tail); /* Get target address */
  89.                         /* within the queue;    */
  90.                         /* then    move object     */
  91.                         /* into it:        */
  92.  
  93.     for( i = qp->objsize;  --i >= 0;  *bp++ = *obj++ )
  94.         ;
  95.  
  96.     if( ++qp->tail >= qp->size)         /* Wrap around if we've    */
  97.         qp->tail = 0;            /* gone off the end of    */
  98.                         /* the queue.        */
  99.     return 1;
  100. }
  101.  
  102. dequeue( obj, qp )
  103. char    *obj ;
  104. QUEUE    *qp  ;
  105. {
  106.     /*    Get an object from the queue. Qp is a pointer to a QUEUE,
  107.      *    The dequeued object is copied into the place pointed to by
  108.      *    obj. Return 0 if the queue is empty and no object was
  109.      *    dequeued, 1 otherwise.
  110.      */
  111.  
  112.     register int    i;
  113.     register char    *bp;
  114.     
  115.     if( qp->nobj <= 0 )
  116.         return 0;                /* queue empty */
  117.  
  118.     qp->nobj-- ;
  119.  
  120.     bp = qp->start + (qp->objsize * qp->head) ;
  121.  
  122.     for( i = qp->objsize; --i >= 0; *obj++ = *bp++ )
  123.         ;
  124.  
  125.     if( ++qp->head >= qp->size )
  126.         qp->head = 0;
  127.  
  128.     return 1;
  129. }
  130.  
  131. /*----------------------------------------------------------------------*/
  132. /*  Little access routines:                        */
  133. /*    Show_next returns a pointer to the object at the head of the    */
  134. /*    queue; sp_used returns the number of objects in the queue    */
  135. /*    sp_avail returns the number of slots available in the queue.    */
  136.  
  137. char    *show_next (qp)
  138. QUEUE    *qp;
  139. {
  140.     return( qp->start + (qp->head * qp->objsize)  );
  141. }
  142.  
  143. int    sp_used    (qp)
  144. QUEUE    *qp;
  145. {
  146.     return( qp->nobj );
  147. }
  148.  
  149. int    sp_avail   (qp)
  150. QUEUE    *qp;
  151. {
  152.     return( qp->size - qp->nobj );
  153. }
  154.  
  155. #ifdef DEBUG
  156.  
  157. main()
  158. {
  159.     int    num, c, *ip;
  160.     QUEUE    *qp;
  161.  
  162.     qp = makequeue( 4, sizeof(int) );
  163.  
  164.     while( 1 )
  165.     {
  166.         num = c = -1;
  167.  
  168.         ip = (int *)qp->start ;
  169.  
  170.         printf("\n\nqueue: %d %d %d %d\n",ip[0],ip[1],ip[2],ip[3]);
  171.  
  172.         printf("start      =0x%x\n",    qp->start    );
  173.         printf("head      =%d\n",    qp->head    );
  174.         printf("tail      =%d\n",    qp->tail    );
  175.         printf("size      =%d\n",    qp->size    );
  176.         printf("objsize   =%d\n",    qp->objsize     );
  177.         printf("nobj      =%d\n",    qp->nobj    );
  178.  
  179.         printf("there are %d slots left in the queue\n\n",
  180.                             sp_avail(qp) );
  181.  
  182.         printf("(d/e/q) ->");
  183.         while( c != 'e' && c != 'd' && c != 'q' )
  184.             c = getchar();
  185.  
  186.         if( c == 'e' )
  187.         {            
  188.             printf("enter decimal number ->");
  189.             scanf("%d", &num );
  190.             printf("enqueue(%d) returned %d\n",
  191.                         num, enqueue(&num,qp) );
  192.         }
  193.         else if( c == 'd' )
  194.         {
  195.             printf( "dequeue returned %d, loaded %d\n",
  196.                         dequeue( &num, qp ), num );
  197.         }
  198.         else
  199.             break;
  200.     }
  201.  
  202.     printf(" deleting queue, queue was %sempty\n",    
  203.                     del_queue(qp) ? "" : "not " );
  204. }
  205.  
  206. #endif
  207.